package xcmg.device.web.safetyStock;

import io.swagger.annotations.ApiOperation;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import xcmg.device.dao.entity.safetyStock.ComSafetyStockInfo;
import xcmg.device.dao.entity.safetyStock.MaterialsSafetyStock;
import xcmg.device.dao.entity.safetyStock.MaterialsSalesData;
import xcmg.device.dao.mapper.safetyStock.MaterialsSalesDataMapper;
import xcmg.device.infra.BasicController;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.purchase.MaterialsPurchaseInfoService;
import xcmg.device.service.safetyStock.ComSafetyStockInfoService;
import xcmg.device.service.safetyStock.MaterialsSafetyStockService;
import xcmg.device.service.safetyStock.MaterialsSalesDataService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.util.TaskUtils;
import yb.ecp.fast.infra.annotation.FastMappingInfo;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;

import java.util.List;
import yb.ecp.fast.infra.infra.log.LogHelper;

/**
 * @author wangyong
 */
@RestController
@RequestMapping("/safetyStock")
public class MaterialsSafetyStockController extends BasicController {

    @Autowired
    private MaterialsSafetyStockService materialsSafetyStockService;

    @Autowired
    private MaterialsSalesDataService materialsSalesDataService;

    @Autowired
    private MaterialsSalesDataMapper materialsSalesDataMapper;

    @Autowired
    private MaterialsPurchaseInfoService materialsPurchaseInfoService;

    @Autowired
    private ComSafetyStockInfoService comSafetyStockInfoService;

    private static final String KEY_PLAN_CODE = "planCode";
    private static final String KEY_MONTH_BEFORE_NO = "monthBeforeNo";

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult save(@RequestBody MaterialsSafetyStock materialsSafetyStock) {
        if (StringUtils.isBlank(materialsSafetyStock.getMaterialsNo())) {
            return actionResult(ErrorCode.Failure, "零件编码不能为空");
        }
        try {
            if (StringUtils.isBlank(materialsSafetyStock.getOrgId())) {
                materialsSafetyStock.setOrgId(getOrgId());
            }
            materialsSafetyStockService.saveMaterialsSafetyStock(materialsSafetyStock);
            return actionResult(ErrorCode.Success);
        } catch (Exception e) {
            return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage());
        }
    }

    @RequestMapping(value = "/batchSave", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult batchSave(String materialsNos) {
        if (StringUtils.isBlank(materialsNos)) {
            return actionResult(ErrorCode.Failure, "未输入任何字符");
        }
        List<String> materialsNoList = getMaterialsNoList(materialsNos);

        if (materialsNoList.size() > 500) {
            return actionResult(ErrorCode.Failure, "为避免等待时间过长，单次请输入小于500条零件");
        }

        List<String> errorNos = new ArrayList<>();
        for (String materialsNo : materialsNoList) {
            try {
                MaterialsSafetyStock materialsSafetyStock = new MaterialsSafetyStock();
                materialsSafetyStock.setOrgId(getOrgId());
                materialsSafetyStock.setMaterialsNo(materialsNo);
                materialsSafetyStockService.saveMaterialsSafetyStock(materialsSafetyStock);
            } catch (Exception e) {
                errorNos.add(materialsNo);
            }
        }
        if (CollectionUtils.isNotEmpty(errorNos)) {
            return actionValueResult("零件：" + errorNos + "生成安全库存失败");
        }
        return actionResult(ErrorCode.Success);
    }
    
    private List<String> getMaterialsNoList(String materialsNos) {
        List<String> materialsNoList = new ArrayList<>();
        if (StringUtils.isBlank(materialsNos)) {
            return materialsNoList;
        }
        String[] nos = materialsNos.split("\\s+|,|，|、|;|；");
        for (String no :nos) {
            if (StringUtils.isNotBlank(no)) {
                materialsNoList.add(no);
            }
        }
        return materialsNoList;
    }
    
    

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult update(@RequestBody List<MaterialsSafetyStock> list) {
        ErrorCode errorCode;
        try {
            errorCode = materialsSafetyStockService.update(list, getUserId(), getUserName());
        } catch (Exception e) {
            return actionResult(ErrorCode.Failure, e.getMessage());
        }
        return actionResult(errorCode);
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult list(@RequestBody SearchCommonVO<MaterialsSafetyStock> condition) throws Exception {
        condition.getFilters().setOrgId(getOrgId());
        PageCommonVO pageCommonVO = materialsSafetyStockService.list(condition);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    /**
     * 临时功能。刷新公司下某月所有的销售数据
     *
     * @param orgId
     * @param planCode
     * @param monthBeforeNo
     * @return
     */
    @RequestMapping(value = "/freshSalesDataByMonth", method = RequestMethod.GET)
    public ActionResult freshSalesDataByMonth(String orgId, String planCode, Integer monthBeforeNo)
        throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String startTime = sdf.format(new Date());
        if (StringUtils.isBlank(orgId) || StringUtils.isBlank(planCode) || null == monthBeforeNo
            || monthBeforeNo < 1 || monthBeforeNo > 13) {
            return actionResult(ErrorCode.Failure, "参数不正确");
        }
        List<MaterialsSalesData> salesDataList = materialsSalesDataMapper.listAllByOrgId(orgId);
        if (CollectionUtils.isEmpty(salesDataList)) {
            return null;
        }
        try {
            Map<String, Object> map = new HashMap<>();
            map.put(KEY_PLAN_CODE, planCode);
            map.put(KEY_MONTH_BEFORE_NO, monthBeforeNo);
            Method method = this.getClass().getDeclaredMethod("updateMaterialsSalesData",List.class, Map.class);
            method.setAccessible(true);
            TaskUtils.excuteTask(salesDataList, this, map, method, 8);
        } catch (Exception e) {
            LogHelper.fatal("MaterialsSafetyStockController#freshSalesDataByMonth is error.", e);
        }
        String endTime = sdf.format(new Date());
        return actionResult(ErrorCode.Success, startTime + "——" + endTime);
    }

    private void updateMaterialsSalesData(List<MaterialsSalesData> salesDataList, Map<String, Object> map) {
        for (MaterialsSalesData materialsSalesData : salesDataList) {
            try {
                materialsSalesDataService.genSpecialMonthSalesData(materialsSalesData, (String) map.get(KEY_PLAN_CODE), (Integer) map.get(KEY_MONTH_BEFORE_NO));
            } catch (Exception e) {
                LogHelper.fatal("MaterialsSafetyStockController#updateMaterialsSalesData is error.orgId:"
                    + materialsSalesData.getOrgId() + ", materialsNo:" + materialsSalesData.getMaterialsNo(), e);
            }
        }
    }

    /**
     * 同步供应商信息, 初始化数据之用，临时功能
     * @param tailNum 零件号尾数
     *
     * @throws Exception
     */
    @RequestMapping(value = "syncPurchaseInfo",method = RequestMethod.GET)
    @ApiOperation(value = "同步供应商信息")
    public ActionResult syncPurchaseInfo(String tailNum) {
        long startTime=System.currentTimeMillis();   //获取开始时间
        List<ComSafetyStockInfo> safetyStockComs = comSafetyStockInfoService.listActiveComs();
        List<String> errorInfo = new ArrayList<>();

        for (ComSafetyStockInfo safetyStockInfo : safetyStockComs) {
            List<MaterialsSalesData> salesDatas = materialsSalesDataService.listBytailNum(safetyStockInfo.getOrgId(), tailNum);
            if (CollectionUtils.isEmpty(salesDatas)) {
                continue;
            }
            excute(salesDatas, safetyStockInfo.getOrgId());
        }
        if(CollectionUtils.isNotEmpty(errorInfo)) {
            System.out.println(errorInfo);
        }
        long endTime=System.currentTimeMillis(); //获取结束时间
        return actionValueResult("程序运行时间： "+(endTime-startTime)+"ms");
    }

    private void excute(List<MaterialsSalesData> salesDatas, String orgId) {
        Map map = new HashMap<>();
        map.put("orgId", orgId);
        try {
            Method method =this.getClass().getDeclaredMethod("syncPurchaseInfo", List.class, Map.class);
            method.setAccessible(true);
            TaskUtils.excuteTask(salesDatas, this, map, method, 8);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    private void syncPurchaseInfo(List<MaterialsSalesData> list, Map map) {
//        for (MaterialsSalesData salesData : list) {
//            try {
//                materialsPurchaseInfoService
//                    .syncMaterialsPurchaseInfo((String)map.get("orgId"), salesData.getMaterialsNo());
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//    }

    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult delete(String materialsNo) {
        try {
            materialsSafetyStockService.delete(materialsNo, getOrgId());
        } catch (Exception e) {
            return actionResult(ErrorCode.Failure, e);
        }
        return actionResult(ErrorCode.Success);
    }

//    @RequestMapping(value = "/syncMaterialsPurchaseInfo", method = RequestMethod.GET)
//    public ActionResult syncMaterialsPurchaseInfo(String orgId, String materialsNo) {
//        return actionResult(materialsPurchaseInfoService.syncMaterialsPurchaseInfo(orgId, materialsNo));
//    }


    @ResponseBody
    @RequestMapping(value = "/importSafetyStock", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult importSafetyStock(HttpServletRequest request) throws Exception{
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile(multipartRequest.getFileNames().next());
        String fileName = file.getOriginalFilename();
        FunctionResult<String> result=new FunctionResult<>();
        if (!fileName.trim().endsWith(".xls")) {
            result.setCode(ErrorCode.ImportExcelEndWithXLS);
        } else {
            result= materialsSafetyStockService.importSafetyStock(file, getOrgId(), getUserId(), getUserName());
        }
        return actionResult(result.getCode(), result.getValue());
    }

    @RequestMapping(value = "/download",method = RequestMethod.POST)
    @ApiOperation("下载价格方案零件导入模板")
    @FastMappingInfo(needLogin = true)
    public void download() throws Exception {
        materialsSafetyStockService.download();
    }

}
